<script lang="ts">
    export default {
        name: 'role'
    };
</script>

<script setup lang="ts">
    import {
        getRolePage,
        updateRole,
        getRoleForm,
        addRole,
        deleteRoles,
        getRoleMenuIds,
        updateRoleMenus
    } from '@/api/role';
    import { listMenuOptions } from '@/api/menu';

    import { RolePageVO, RoleForm, RoleQuery } from '@/api/role/types';

    const queryFormRef = ref(ElForm);
    const roleFormRef = ref(ElForm);
    const menuRef = ref(ElTree);

    const loading = ref(false);
    const ids = ref < number[] > ([]);
    const total = ref(0);

    const queryParams = reactive < RoleQuery > ({
        pageNum: 1,
        pageSize: 10
    });

    const roleList = ref < RolePageVO[] > ();

    const dialog = reactive < DialogOption > ({
        visible: false
    });

    const formData = reactive < RoleForm > ({
        sort: 1,
        status: 1,
        code: '',
        name: ''
    });

    const rules = reactive({
        name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
        code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }],
        // dataScope: [{ required: true, message: '请选择数据权限', trigger: 'blur' }],
        status: [{ required: true, message: '请选择状态', trigger: 'blur' }]
    });

    const menuDialogVisible = ref(false);

    const menuList = ref < OptionType[] > ([]);

    interface CheckedRole {
        id?: number;
        name?: string;
    }
    let checkedRole: CheckedRole = reactive({});

    /**
     * 查询
     */
    function handleQuery() {
        loading.value = true;
        getRolePage(queryParams)
            .then(({ data }) => {
                roleList.value = data.list;
                total.value = data.total;
            })
            .finally(() => {
                loading.value = false;
            });
    }
    /**
     * 重置查询
     */
    function resetQuery() {
        queryFormRef.value.resetFields();
        queryParams.pageNum = 1;
        handleQuery();
    }

    /**
     * 行checkbox change事件
     */
    function handleSelectionChange(selection: any) {
        ids.value = selection.map((item: any) => item.id);
    }

    /**
     * 打开角色表单弹窗
     *
     * @param roleId
     */
    function openDialog(roleId?: number) {
        dialog.visible = true;
        if (roleId) {
            dialog.title = '修改角色';
            getRoleForm(roleId).then(({ data }) => {
                Object.assign(formData, data);
            });
        } else {
            dialog.title = '新增角色';
        }
    }

    /**
     * 角色表单提交
     */
    function handleSubmit() {
        loading.value = true;
        roleFormRef.value.validate((valid: any) => {
            if (valid) {
                const roleId = formData.id;
                if (roleId) {
                    updateRole(roleId, formData)
                        .then(() => {
                            ElMessage.success('修改成功');
                            closeDialog();
                            resetQuery();
                        })
                        .finally(() => (loading.value = false));
                } else {
                    addRole(formData)
                        .then(() => {
                            ElMessage.success('新增成功');
                            closeDialog();
                            resetQuery();
                        })
                        .finally(() => (loading.value = false));
                }
            }
        });
    }

    /**
     * 关闭弹窗
     */
    function closeDialog() {
        dialog.visible = false;
        resetForm();
    }

    /**
     * 重置表单
     */
    function resetForm() {
        roleFormRef.value.resetFields();
        roleFormRef.value.clearValidate();

        formData.id = undefined;
        formData.sort = 1;
        formData.status = 1;
    }

    /**
     * 删除
     */
    function handleDelete(roleId?: number) {
        const roleIds = [roleId || ids.value].join(',');
        if (!roleIds) {
            ElMessage.warning('请勾选删除项');
            return;
        }

        ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }).then(() => {
            loading.value = true;
            deleteRoles(roleIds)
                .then(() => {
                    ElMessage.success('删除成功');
                    resetQuery();
                })
                .finally(() => (loading.value = false));
        });
    }

    /**
     * 打开分配菜单弹窗
     */
    function openMenuDialog(row: RolePageVO) {
        const roleId = row.id;
        if (roleId) {
            checkedRole = {
                id: roleId,
                name: row.name
            };
            menuDialogVisible.value = true;
            loading.value = true;

            // 获取所有的菜单
            listMenuOptions().then(response => {
                menuList.value = response.data;
                // 回显角色已拥有的菜单
                getRoleMenuIds(roleId)
                    .then(({ data }) => {
                        const checkedMenuIds = data;
                        console.log('勾选权限', checkedMenuIds);
                        checkedMenuIds.forEach(menuId =>
                            menuRef.value.setChecked(menuId, true, false)
                        );
                    })
                    .finally(() => {
                        loading.value = false;
                    });
            });
        }
    }

    /**
     * 角色分配菜单提交
     */
    function handleRoleMenuSubmit() {
        const roleId = checkedRole.id;
        if (roleId) {
            const checkedMenuIds: number[] = menuRef.value
                .getCheckedNodes(false, true)
                .map((node: any) => node.value);

            loading.value = true;
            updateRoleMenus(roleId, checkedMenuIds)
                .then(res => {
                    ElMessage.success('分配权限成功');
                    menuDialogVisible.value = false;
                    resetQuery();
                })
                .finally(() => {
                    loading.value = false;
                });
        }
    }

    onMounted(() => {
        handleQuery();
    });
</script>

<template>
    <div class="app-container">
        <!-- <div class="search">
            <el-form ref="queryFormRef" :model="queryParams" :inline="true">
                <el-form-item prop="keywords" label="关键字">
                    <el-input v-model="queryParams.keywords" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
                </el-form-item>

                <el-form-item>
                    <el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
                    <el-button @click="resetQuery"><i-ep-refresh />重置</el-button>
                </el-form-item>
            </el-form>
        </div> -->

        <el-card shadow="never">
            <template #header>
                <el-button type="success" @click="openDialog()" v-hasPerm="['sys:role:add']">
                    <i-ep-plus />新增
                </el-button>
                <el-button type="danger" :disabled="ids.length === 0" @click="handleDelete()"
                    v-hasPerm="['sys:role:delete']">
                    <i-ep-delete />删除
                </el-button>
            </template>

            <el-table ref="dataTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"
                highlight-current-row border>
                <el-table-column type="selection" width="55" align="center" />
                <el-table-column label="角色名称" prop="name" min-width="100" />
                <el-table-column label="角色编码" prop="code" width="150" />

                <el-table-column label="状态" align="center" width="100">
                    <template #default="scope">
                        <el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
                        <el-tag v-else type="info">禁用</el-tag>
                    </template>
                </el-table-column>

                <el-table-column label="排序" align="center" width="80" prop="sort" />

                <el-table-column fixed="right" label="操作" width="220">
                    <template #default="scope">
                        <el-button type="primary" size="small" link @click="openMenuDialog(scope.row)"
                            v-hasPerm="['sys:role:assperm']">
                            <i-ep-position />分配权限
                        </el-button>
                        <el-button type="primary" size="small" link @click="openDialog(scope.row.id)"
                            v-hasPerm="['sys:role:edit']">
                            <i-ep-edit />编辑
                        </el-button>
                        <el-button type="primary" size="small" link @click="handleDelete(scope.row.id)"
                            v-hasPerm="['sys:role:delete']">
                            <i-ep-delete />删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>

            <pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum"
                v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
        </el-card>

        <!-- 角色表单弹窗 -->
        <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" @close="closeDialog">
            <el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="100px">
                <el-form-item label="角色名称" prop="name">
                    <el-input v-model="formData.name" placeholder="请输入角色名称" />
                </el-form-item>

                <el-form-item label="角色编码" prop="code">
                    <el-input v-model="formData.code" placeholder="请输入角色编码" />
                </el-form-item>

                <!-- <el-form-item label="数据权限" prop="dataScope">
                    <el-select v-model="formData.dataScope">
                        <el-option :key="0" label="全部数据" :value="0" />
                        <el-option :key="1" label="部门及子部门数据" :value="1" />
                        <el-option :key="2" label="本部门数据" :value="2" />
                        <el-option :key="3" label="本人数据" :value="3" />
                    </el-select>
                </el-form-item> -->

                <el-form-item label="状态" prop="status">
                    <el-radio-group v-model="formData.status">
                        <el-radio :label="1">正常</el-radio>
                        <el-radio :label="0">停用</el-radio>
                    </el-radio-group>
                </el-form-item>

                <el-form-item label="排序" prop="sort">
                    <el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
                </el-form-item>
            </el-form>

            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="handleSubmit">确 定</el-button>
                    <el-button @click="closeDialog">取 消</el-button>
                </div>
            </template>
        </el-dialog>

        <!-- 分配菜单弹窗  -->
        <el-dialog :title="'【' + checkedRole.name + '】权限分配'" v-model="menuDialogVisible" width="800px">
            <el-scrollbar max-height="600px" v-loading="loading">
                <el-tree ref="menuRef" node-key="value" show-checkbox :data="menuList" :default-expand-all="true">
                    <template #default="{ data }">
                        {{ data.label }}
                    </template>
                </el-tree>
            </el-scrollbar>

            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="handleRoleMenuSubmit">确 定</el-button>
                    <el-button @click="menuDialogVisible = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>